package tech.yunland.shop.web;

import com.alibaba.fastjson.JSON;
import com.moyuer.bsf.common.Pagination;
import com.moyuer.bsf.domain.model.ConfigItem;
import com.moyuer.bsf.domain.service.ConfigItemService;
import com.moyuer.bsf.web.controller.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import tech.yunland.shop.domain.model.GoodsPaid;
import tech.yunland.shop.domain.model.SaleBill;
import tech.yunland.shop.domain.model.SaleBillEntry;
import tech.yunland.shop.domain.model.SaleBillHandler;
import tech.yunland.shop.domain.service.SaleBillService;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.*;

/**
 * 销售单控制器
 *
 * @author 王睿智<geekrize@gmail.com>
 */
@RestController
@RequestMapping("/sale")
public class SaleBillController extends BaseController {

    @Autowired
    private SaleBillService saleBillService;
    @Autowired
    private ConfigItemService configItemService;

    /**
     * 保存销售单
     *
     * @param saleBill
     */
    @RequestMapping(value = "/", method = RequestMethod.POST)
    public void saveOrUpdate(@RequestBody @Valid SaleBill saleBill) {
        // 输出日志
        logger.info(JSON.toJSONString(saleBill, true));

        // 判断组织
        if (saleBill.getOrgan() == null) {
            saleBill.setOrgan(primaryOrgan);
        }

        // 判断创建人
        if (saleBill.getCreator() == null) {
            saleBill.setCreator(this.currentUser);
        }

        if (saleBill.getEntries() == null || saleBill.getEntries().size() == 0) {
            throw new RuntimeException("参数错误, 没有商品信息");
        }

        // 获取当前机构的提成类型
        List<ConfigItem> configItems = configItemService.getList("prize_type", primaryOrganId);

        ConfigItem configItem = null;
        if (configItems != null && configItems.size() > 0) { //设置了提成类型
            if (configItems.size() != 1) {
                throw new RuntimeException("未正确设置提成类型");
            }
            configItem = configItems.get(0);
        }

        if (saleBill.getState().equals(1)) {
            saleBillService.saveAndPay("ordinary", configItem, saleBill);

            // 保存日志
            saveLog("单据编号:[" + saleBill.getSn() + "]收银结算成功！");
        } else {
            saleBillService.saveNotPay(saleBill);

            // 保存日志
            saveLog("单据编号:[" + saleBill.getSn() + "]收银挂单成功！");
        }
    }

    /**
     * 根据主键获取销售单
     *
     * @param id
     * @Return GoodsPackage
     */
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public SaleBill get(@PathVariable String id) {
        SaleBill bill = saleBillService.get(id);
        if (bill != null) {
            Set<SaleBillEntry> entries = bill.getEntries();
            if (bill.getMember() != null) {
                HashSet<SaleBillEntry> newEntries = new HashSet<>();
                for (SaleBillEntry entry : entries) {
                    BigDecimal memberPrize = entry.getGoodsPrice();
                    GoodsPaid goodsPaid = saleBillService.getGoodsPaid(entry.getGoodsId().toString(),
                            bill.getOrgan().getId().toString(), bill.getMember().getId().toString());
                    if (goodsPaid != null) {
                        int quantityRate = goodsPaid.getQuantity().compareTo(BigDecimal.ZERO);
                        if (quantityRate != 0) {
                            memberPrize = goodsPaid.getAmount().divide(goodsPaid.getQuantity(), 2, BigDecimal.ROUND_HALF_UP);
                        }
                    }
                    entry.setMemberPrize(memberPrize);
                    newEntries.add(entry);
                }
                bill.setEntries(newEntries);
            }
        }
        return bill;
    }

    @RequestMapping(value = "/sn/{id}")
    public Pagination<HashMap<String, Object>> getByKey(@PathVariable String id
            , @RequestParam(required = false) Integer page, @RequestParam(required = false) Integer rows) {
        Pagination<HashMap<String, Object>> result = new Pagination<HashMap<String, Object>>(page, rows);
        int startIdx = result.getStartIdx();
        int count = saleBillService.getCount(id);
        List<HashMap<String, Object>> records = saleBillService.getByKey(id, startIdx, rows);

        SaleBill bill = saleBillService.get(id);

        List<HashMap<String, Object>> newRecords = new ArrayList<>();
        for (HashMap<String, Object> args : records) {
            BigDecimal memberPrize = BigDecimal.valueOf(Double.valueOf(args.get("goodsprice").toString()));

            if (bill.getMember() != null) { //如果是会员的话，则计算会员价
                GoodsPaid goodsPaid = saleBillService.getGoodsPaid(args.get("goods_id").toString(),
                        bill.getOrgan().getId().toString(), bill.getMember().getId().toString());

                if (goodsPaid != null) {
                    int quantityRate = goodsPaid.getQuantity().compareTo(BigDecimal.ZERO);
                    if (quantityRate != 0) {
                        memberPrize = goodsPaid.getAmount().divide(goodsPaid.getQuantity(), 2, BigDecimal.ROUND_HALF_UP);
                    }
                }
            }

            args.put("memberPrice", memberPrize);
            newRecords.add(args);

        }

        result.setCount(count);
        result.setRecords(records);
        return result;

    }

    /**
     * 根据主键删除销售单
     *
     * @param id
     * @Return
     */
    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    public void delete(@PathVariable String id) {

        SaleBill saleBill = saleBillService.get(id);

        saleBillService.delete(id);

        saveLog("单据编号:[" + saleBill.getSn() + "]收银记录删除成功！");

    }

    /**
     * 查询结算与未结算状态销售单
     *
     * @param param 参数
     * @param page  起始索引
     * @param rows  每页数量
     * @return
     * @Return List<SaleBill>
     */
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public Pagination<SaleBill> getResultInfos(@RequestParam(required = false) String param,
                                               @RequestParam(required = false) List<Integer> states,
                                               @RequestParam(required = false) String[] goodsId,
                                               @RequestParam(required = false) Integer page,
                                               @RequestParam(required = false) Integer rows) {

        Pagination<SaleBill> result = new Pagination<SaleBill>(page, rows);
        int startIdx = result.getStartIdx();

        int count = saleBillService.getResultSize(param, states, goodsId, organIds);
        List<SaleBill> records = saleBillService.getResultInfos(param, states, goodsId, startIdx, rows, organIds);

        for (SaleBill bill : records) {
            Set<SaleBillEntry> entries = bill.getEntries();
            BigDecimal total = BigDecimal.ZERO;
            for (SaleBillEntry entry : entries) {
                total = total.add(entry.getAmount());
            }
            bill.setReceived(total);
        }

        result.setCount(count);
        result.setRecords(records);

        return result;
    }

    /**
     * 查询未结算的销售单分录
     *
     * @param param   参数
     * @param goodsId 商品ID
     * @param page    起始索引
     * @param rows    每页数量
     * @return
     * @Return List<SaleBill>
     */
    @RequestMapping(value = "/on-shelf", method = RequestMethod.GET)
    public Pagination<SaleBill> getOnShelfGoods(@RequestParam(required = false) String param,
                                                @RequestParam(required = false) List<Integer> states, @RequestParam(required = false) String[] goodsId,
                                                @RequestParam(required = false) Integer page, @RequestParam(required = false) Integer rows) {

        // Integer[] states = new Integer[]{0};

        Pagination<SaleBill> result = new Pagination<SaleBill>(page, rows);
        int startIdx = result.getStartIdx();

        int count = saleBillService.getResultSize(param, states, goodsId, organIds);
        List<SaleBill> records = saleBillService.getResultInfos(param, states, goodsId, startIdx, rows, organIds);

        result.setCount(count);
        result.setRecords(records);

        return result;
    }

    /**
     * 查询结算与未结算的销售单分录
     *
     * @param owner 主表ID
     * @param page  起始索引
     * @param rows  每页数量
     * @return
     * @Return List<SaleBillEntry>
     */
    @RequestMapping(value = "/entry", method = RequestMethod.GET)
    public Pagination<SaleBillEntry> getSaleEntry(@RequestParam(required = false) String owner,
                                                  @RequestParam(required = false) List<Integer> states, @RequestParam(required = false) Integer page,
                                                  @RequestParam(required = false) Integer rows) {

        // Integer[] states = new Integer[]{0, 1};

        Pagination<SaleBillEntry> result = new Pagination<SaleBillEntry>(page, rows);
        int startIdx = result.getStartIdx();

        int count = saleBillService.getEntryResultSize(null, owner, states);
        List<SaleBillEntry> records = saleBillService.getEntryResultInfos(null, owner, states, startIdx,
                rows);

        result.setCount(count);
        result.setRecords(records);

        return result;
    }

    /**
     * 查询结算与未结算的销售单分录 <不分页>
     *
     * @param owner 主表ID
     * @Return List<SaleBillEntry>
     */
    @RequestMapping(value = "/entry/list", method = RequestMethod.GET)
    public List<SaleBillEntry> getSaleEntry(@RequestParam(required = false) String owner,
                                            @RequestParam(required = false) List<Integer> states) {
        List<SaleBillEntry> records = saleBillService.getEntryResultInfos(null, owner, states, Integer.valueOf(-1),
                Integer.valueOf(-1));
        return records;
    }


    /**
     * 销售结算或挂单, 即添加销售单分录
     *
     * @param entriesId
     * @param memberId
     * @param payment
     * @param receivable
     * @param received
     */
    @RequestMapping(value = "/entry", method = RequestMethod.POST)
    public void addSaleBillEntry(@RequestParam List<String> entriesId, @RequestParam(required = false) String memberId,
                                 @RequestParam(required = false) Integer payment, @RequestParam BigDecimal receivable,
                                 @RequestParam BigDecimal received,
                                 @RequestParam(required = false) String remark) {

        // 获取当前机构的提成类型
        List<ConfigItem> configItems = configItemService.getList("prize_type", primaryOrganId);
        if (configItems == null || configItems.size() != 1) {
            throw new RuntimeException("未正确设置提成类型");
        }

        ConfigItem configItem = configItems.get(0);

        saleBillService.payEntries(payment, configItem, entriesId, memberId, currentUser, receivable, received,remark);

    }

    /**
     * 查询销售单经办人
     *
     * @param saleBillEntry 分录ID
     * @param page          起始索引
     * @param rows          每页数量
     * @return List<SaleBillHandler>
     */
    @RequestMapping(value = "/handler", method = RequestMethod.GET)
    public Pagination<SaleBillHandler> getSaleBillHandler(@RequestParam(required = false) String saleBillEntry,
                                                          @RequestParam(required = false) Integer page, @RequestParam(required = false) Integer rows) {

        Pagination<SaleBillHandler> result = new Pagination<SaleBillHandler>(page, rows);
        int startIdx = result.getStartIdx();

        int count = saleBillService.getHandlerResultSize(saleBillEntry);
        List<SaleBillHandler> records = saleBillService.getHandlerResultInfos(saleBillEntry, startIdx, rows);

        result.setCount(count);
        result.setRecords(records);

        return result;
    }

    /**
     * 根据赊帐单还款
     *
     * @param id
     */
    @RequestMapping(value = "/repayment/{id}", method = RequestMethod.GET)
    public void repayment(@PathVariable String id) {
        saleBillService.repayment(id);
    }

    @RequestMapping(value = "/getEntry/{id}",method = RequestMethod.GET)
    public SaleBillEntry getSaleBillEntry(@PathVariable String id){
        return this.saleBillService.getSaleBillEntry(id);
    }
}













